// friendService.cpp
#include "friend.pb.h"
#include "rpc_channel.h"
#include "rpc_provider.h"

#include <chrono>
#include <future>
#include <iostream>
#include <map>
#include <memory> // 添加智能指针支持
#include <string>
#include <thread>
#include <vector>

class FriendService : public fixbug::FriendServiceRpc {
public:
    // 模拟一个好友列表
    static std::map<uint32_t, std::vector<std::string>> userFriendsMap;

    static std::vector<std::string> GetFriendsList(uint32_t userid) {
        return userFriendsMap[userid % 10]; // 取模以防止越界
    }

    // 重写基类方法
    void GetFriendsList(::google::protobuf::RpcController*     controller,
                        const ::fixbug::GetFriendsListRequest* request,
                        ::fixbug::GetFriendsListResponse*      response,
                        ::google::protobuf::Closure*           done) {
        std::cout << "do GetFriendsList service! request userid = " << request->userid() << std::endl;
        uint32_t                 userid      = request->userid();
        std::vector<std::string> friendsList = GetFriendsList(userid);
        response->mutable_result()->set_errcode(0);
        response->mutable_result()->set_errmsg("");
        for (std::string& name : friendsList) {
            std::string* p = response->add_friends();
            *p             = name;
        }
        std::this_thread::sleep_for(std::chrono::seconds(1)); // 模拟耗时操作
        done->Run();
    }

    // 重写基类方法
    void AsyncGetFriendsList(::google::protobuf::RpcController*     controller,
                             const ::fixbug::GetFriendsListRequest* request,
                             ::fixbug::GetFriendsListResponse*      response,
                             ::google::protobuf::Closure*           done) {
        // assert(controller != nullptr); // 确保 controller 不为空
        assert(request != nullptr);  // 确保 request 不为空
        assert(response != nullptr); // 确保 response 不为空
        assert(done != nullptr);     // 确保 done 不为空

        uint32_t userid_val = request->userid();

        // request 对象将在该调用结束后被销毁，因此需要确保在异步任务中不要使用原始的 request 对象。
        std::thread t([userid_val, response, done, controller]() {
            // ... 业务逻辑，填充 response ...
            try {
                uint32_t                 mod_userid  = userid_val % 10;
                std::vector<std::string> friendsList = GetFriendsList(mod_userid);
                response->mutable_result()->set_errcode(0);
                response->mutable_result()->set_errmsg("");
                // ... 填充 response ...
                for (std::string& name : friendsList) {
                    std::string* p = response->add_friends();
                    *p             = name;
                }
                std::this_thread::sleep_for(std::chrono::milliseconds(10));

            } catch (const std::exception& e) {
                if (response) {
                    response->mutable_result()->set_errcode(-1);
                    response->mutable_result()->set_errmsg(std::string("Server exception: ") + e.what());
                }
            }
            // ... 其他异常处理 ...

            std::cout << "Async task finished! For userid = " << userid_val << ", the response obj is: " << response
                      << std::endl;
            for (int i = 0; i < response->friends_size(); i++) {
                std::cout << response->friends(i) << " ";
            }
            std::cout << std::endl;

            // 调用原始的 done
            if (done) {
                done->Run(); // 这一步应该放到最后执行
            }
        });
        t.detach();
    }
};

std::map<uint32_t, std::vector<std::string>> FriendService::userFriendsMap = {
    {0, {"User0_Friend0", "User0_Friend1", "User0_Friend2", "User0_Friend3"}},
    {1, {"User1_Friend0", "User1_Friend1", "User1_Friend2", "User1_Friend3", "User1_Friend4"}},
    {2,
     {"User2_Friend0",
      "User2_Friend1",
      "User2_Friend2",
      "User2_Friend3",
      "User2_Friend4",
      "User2_Friend5",
      "User2_Friend6"}},
    {3, {"User3_Friend0", "User3_Friend1", "User3_Friend2"}},
    {4, {"User4_Friend0", "User4_Friend1", "User4_Friend2", "User4_Friend3", "User4_Friend4", "User4_Friend5"}},
    {5, {"User5_Friend0", "User5_Friend1", "User5_Friend2", "User5_Friend3"}},
    {6, {"User6_Friend0", "User6_Friend1", "User6_Friend2", "User6_Friend3", "User6_Friend4"}},
    {7, {"User7_Friend0", "User7_Friend1", "User7_Friend2", "User7_Friend3", "User7_Friend4"}},
    {8, {"User8_Friend0", "User8_Friend1", "User8_Friend2", "User8_Friend3", "User8_Friend4"}},
    {9, {"User9_Friend0", "User9_Friend1", "User9_Friend2", "User9_Friend3"}}};

int main(int argc, char** argv) {
    // std::string ip   = "127.0.0.1";
    short port = 7788;

    // provider是一个rpc网络服务对象。把UserService对象发布到rpc节点上
    RpcProvider provider;
    provider.NotifyService(new FriendService());

    // 启动一个rpc服务发布节点 Run以后，进程进入阻塞状态，等待远程的rpc调用请求
    provider.Run(1, port);

    return 0;
}
